package com.caits.lbs.framework.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.caits.lbs.framework.Constants;
import com.caits.lbs.framework.bean.common.Cell;
import com.caits.lbs.framework.bean.common.ECondition;
import com.caits.lbs.framework.bean.common.Row;
import com.caits.lbs.framework.bean.common.Rows;
import com.caits.lbs.framework.log.CommonLogFactory;
import com.caits.lbs.framework.utils.StringUtils;
import com.caits.lbs.framework.utils.XmlUtil;
import com.common.ajax.server.IRequest;
import com.common.ajax.server.RequestLocalParser;
import com.opensymphony.xwork2.ActionSupport;

/**
 * <p>
 * BaseAction
 * </p>
 * <p>
 * 用途：基础的action,所有的业务action都继承此action
 * 提供了处理接口IRequest，全局配置类Constants,session对象，通用xml包装
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 * @version 0.0.1 2011-8-25
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-8-25 下午2:38:12</td>
 *          </tr>
 *          <tr>
 *          <td>0.0.1</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-8-25 下午2:38:12</td>
 *          <td>0.0.2</td>
 *          <td>修改类</td>
 *          <td>xxx</td>
 *          <td>x年x月x日</td>
 *          </tr>
 *          </table>
 */
public class BaseAction extends ActionSupport implements SessionAware,
		ServletRequestAware, ServletResponseAware {
	/** 序列号 */
	private static final long serialVersionUID = 1L;

	/**内容编码参见网址
	 * http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html*
	 */
	/** 内容编码utf-8 */
	public final static String ContentTypeUtf8 = "UTF-8";
	/** 内容类型(html,utf-8) */
	public final static String ContentTypeHtml = "text/html;charset=utf-8";
	/** 内类型 (xml格式,utf-8)*/
	public final static String ContentTypeXML = "text/xml;charset=utf-8";
	/** 内容类型(jscript脚本) */
	public final static String ContentTypeScript = "text/javascript;charset=utf-8";
	/** 内容类型(json数据) */
	public final static String ContentTypeJson = "application/json;charset=UTF-8";
	/** 内容类型(二进制流格式)*/
	public final static String ContentTypeBin = "application/octet-stream";
	/** 内容类型(压缩文件格式)*/
	public final static String ContentTypeZip = "application/zip";
	
	/** log4j 日志记录器 */
	protected Logger log = CommonLogFactory.getLog();

	/** 请求 */
	private HttpServletRequest request;
	/** 响应 */
	private HttpServletResponse response;
	/** 存放一个会话对象 */
	private Map<String, Object> session;
	/** 处理对象 */
	private IRequest serviceParser;

	/** 全局常量配置 */
	private Constants constants;

	private ECondition condition;

	private String xmlStr;// 客户端发送的get请求参数字符串,a=1&b=2...的形式

	/** bean的名称 */
	private String modelName;
	/** 方法名称 */
	private String typeName;
	/** 服务类名称 */
	private String serverName;

	/**
	 * 构造器
	 */
	public BaseAction() {
		super();
	}

	// **************************************************************************

	public HttpServletRequest getRequest() {
		return request;

	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	public HttpServletResponse getResponse() {
		return response;
	}

	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}

	public Map<String, Object> getSession() {
		return session;
	}

	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	public void setServletRequest(HttpServletRequest arg0) {
		this.request = arg0;
	}

	public void setServletResponse(HttpServletResponse arg0) {
		this.response = arg0;
	}

	/**
	 * 返回grid字符串
	 * 
	 * @param xmlString
	 * @param pages
	 * @return
	 */
	public String reponseGridXMl(String xmlString, int pages) {
		String reString = null;
		// request.getReader();
		Document requestDoc = null;
		requestDoc = XmlUtil.StringTodocument(xmlString);

		Element root = requestDoc.getRootElement();
		Element c1 = root.element("data");

		Rows rows = new Rows();

		String total = c1.attributeValue("total");
		String totalPages = c1.attributeValue("pages");
		String isonline = c1.attributeValue("isonline");
		String isnotonline = c1.attributeValue("isnotonline");
		if (total == null)
			total = "0";
		if (totalPages == null)
			totalPages = "0";
		if (isonline == null)
			isonline = "0";
		if (isnotonline == null)
			isnotonline = "0";
		// 当前页
		rows.setPage(pages);
		// 总行数
		rows.setTotal(Integer.parseInt(total));

		rows.setIsonline(Integer.parseInt(isonline));
		rows.setIsnotonline(Integer.parseInt(isnotonline));

		List<Row> r = new ArrayList<Row>();
		// 得到列表
		List<Element> cs = c1.elements();
		if (cs != null) {
			for (Element e : cs) {
				// 每行
				Row row = new Row();
				row.setId(e.attributeValue("id"));
				// 每列
				List<Cell> c = new ArrayList<Cell>();
				List<Attribute> atts = e.attributes();
				for (Attribute string : atts) {
					Cell cell = new Cell();
					cell.setName(string.getName());
					cell.setElemntValue(string.getValue());

					c.add(cell);
				}
				row.setCell(c);
				r.add(row);
			}
		}
		rows.setRow(r);
		// Element e = rows.toElement();
		reString = rows.toXml();
		reString = "<?xml version='1.0' encoding='utf-8'?>" + reString;
		log.info("返回的结果："
				+ reString.substring(
						0,
						Math.min(constants.getMax_log_output(),
								reString.length())));
		return reString;
	}

	/**
	 * 接收客户端请求，并调用IRequest进行处理，返回相应结果给客户端
	 */
	public void parseXmlString() {
		HttpServletResponse response = getResponse();
		response.setContentType(ContentTypeXML);
		PrintWriter pw = null;
		try {
			pw = response.getWriter();
		} catch (IOException e) {
			log.debug("系统错误" + e);
		}

		Document doc = null;
		try {
			doc = serviceParser.request(getRequestDoc(),
					RequestLocalParser.getSession(getRequest()));
		} catch (SecurityException e) {
			log.error("服务处理安全错误," + e.getLocalizedMessage(), e);
		} catch (NoSuchMethodException e) {
			log.error("服务处理方法错误," + e.getLocalizedMessage(), e);
		} catch (IllegalAccessException e) {
			log.error("服务处理非法访问错误," + e.getLocalizedMessage(), e);
		} catch (InvocationTargetException e) {
			log.error("服务处理呼叫目标错误," + e.getLocalizedMessage(), e);
		} catch (SQLException e) {
			log.error("服务处理数据库错误," + e.getLocalizedMessage(), e);
		} catch (RuntimeException e) {
			log.error("服务处理运行时错误," + e.getLocalizedMessage(), e);
		}
		String str = XmlUtil.documentToString(doc);
		log.info("返回的结果：" + prettyStringLengh(str));
		pw.print(str);// 返回相应结果
	}

	/**
	 * 获取变量<code>constants</code>的值
	 * 
	 * @return 返回的数据类型是<code>Constants</code>
	 */
	public Constants getConstants() {
		return constants;
	}

	/**
	 * 设置变量<code> constants</code> 的值
	 * 
	 * @param constants
	 *            <code>constants</code> 参数类型是<code>Constants</code>
	 */
	public void setConstants(Constants constants) {
		this.constants = constants;
	}

	/**
	 * 解析get请求参数，转换成xml请求
	 * 
	 * @return
	 */
	public Document getRequestDoc() {
		Element tr = DocumentHelper
				.createElement(StringUtils.null2default(getModelName(),"test"));
		if (xmlStr != null && !xmlStr.equals("")) {
			String[] arr1 = xmlStr.split("&");
			if (arr1 != null) {
				for (String string : arr1) {
					if (string != null && !string.trim().equals("")) {
						String[] arr2 = string.split("=",2);
						if (arr2.length != 2) {
							log.error("参数解析错误,置空,"+arr2.toString());
							tr.addAttribute(arr2[0],"");
						} else {
							tr.addAttribute(arr2[0], arr2[1]);
						}
					}
				}
			}
		}
		Element data = DocumentHelper.createElement(IRequest.XML_DATA);
		data.addAttribute(IRequest.XML_TYPE,
				StringUtils.null2default(getTypeName(), "test"));
		if (condition != null) {
			tr.addAttribute("page", String.valueOf(condition.getPage()));
			tr.addAttribute("size", String.valueOf(condition.getRows()));
		}
		data.add(tr);
		Element req = DocumentHelper.createElement(IRequest.XML_REQUEST);
		req.addAttribute(IRequest.XML_SERVER,
				StringUtils.null2default(getServerName(), "test"));
		req.add(data);
		Document responseDoc = DocumentHelper.createDocument(req);
		log.info("请求的XMl：" + prettyStringLengh(responseDoc.asXML()));
		return responseDoc;

	}

	/**
	 * 取得系统打印的许可长度
	 * 
	 * @param asXML
	 * @return
	 */
	protected String prettyStringLengh(String asXML) {

		return asXML == null ? null : asXML.substring(0,
				Math.min(constants.getMax_log_output(), asXML.length()));

	}

	/**
	 * 获取变量<code>condition</code>的值
	 * 
	 * @return 返回的数据类型是<code>ECondition</code>
	 */
	public ECondition getCondition() {
		return condition;
	}

	/**
	 * 设置变量<code> condition</code> 的值
	 * 
	 * @param condition
	 *            <code>condition</code> 参数类型是<code>ECondition</code>
	 */
	public void setCondition(ECondition condition) {
		this.condition = condition;
	}

	/**
	 * 获取变量<code>xmlStr</code>的值
	 * 
	 * @return 返回的数据类型是<code>String</code>
	 */
	public String getXmlStr() {
		return xmlStr;
	}

	/**
	 * 设置变量<code> xmlStr</code> 的值
	 * 
	 * @param xmlStr
	 *            <code>xmlStr</code> 参数类型是<code>String</code>
	 */
	public void setXmlStr(String xmlStr) {
		this.xmlStr = xmlStr;
	}

	/**
	 * 检查验证码
	 * 
	 * @param code
	 * @return
	 */
	public boolean checkCode(String code) {
		if (code != null) {
			return code.trim().toUpperCase()
					.equals(session.get("RandomCheckCode"));
		}

		return false;
	}

	/**
	 * 获取变量<code>serviceParser</code>的值
	 * 
	 * @return 返回的数据类型是<code>IRequest</code>
	 */
	public IRequest getServiceParser() {
		return serviceParser;
	}

	/**
	 * 设置变量<code> serviceParser</code> 的值
	 * 
	 * @param serviceParser
	 *            <code>serviceParser</code> 参数类型是<code>IRequest</code>
	 */
	public void setServiceParser(IRequest serviceParser) {
		this.serviceParser = serviceParser;
	}

	/**
	 * 获取变量<code>modelName</code>的值
	 * 
	 * @return 返回的数据类型是<code>String</code>
	 */
	public String getModelName() {
		return modelName == null ? getConstants().getModelName() : modelName;
	}

	/**
	 * 设置变量<code> modelName</code> 的值
	 * 
	 * @param modelName
	 *            <code>modelName</code> 参数类型是<code>String</code>
	 */
	public void setModelName(String modelName) {
		this.modelName = modelName;
	}

	/**
	 * 获取变量<code>typeName</code>的值
	 * 
	 * @return 返回的数据类型是<code>String</code>
	 */
	public String getTypeName() {
		return typeName == null ? getConstants().getTypeName() : typeName;
	}

	/**
	 * 设置变量<code> typeName</code> 的值
	 * 
	 * @param typeName
	 *            <code>typeName</code> 参数类型是<code>String</code>
	 */
	public void setTypeName(String typeName) {
		this.typeName = typeName;
	}

	/**
	 * 获取变量<code>serverName</code>的值
	 * 
	 * @return 返回的数据类型是<code>String</code>
	 */
	public String getServerName() {
		return serverName == null ? getConstants().getServerName() : serverName;
	}

	/**
	 * 设置变量<code> serverName</code> 的值
	 * 
	 * @param serverName
	 *            <code>serverName</code> 参数类型是<code>String</code>
	 */
	public void setServerName(String serverName) {
		this.serverName = serverName;
	}
	/**
	 * 清除页面 缓存
	 * @param response
	 */
	public void clearCache(HttpServletResponse response){
		//清除页面
		response.setHeader("Pragma","No-cache");
		response.setHeader("Cache-Control","no-cache");
		response.setHeader("Cache-Control", "no-store");
		response.setDateHeader("Expires", 0);
	}
}
